#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
GPIO20 PWM信号生成器 (使用libgpiod)
每隔5毫秒循环发送2.5ms高电平和2.5ms低电平
"""

import gpiod
import time
import signal
import sys

# GPIO引脚配置
GPIO_PIN = 20
HIGH_TIME = 0.0025  # 2.5毫秒高电平
LOW_TIME = 0.0025   # 2.5毫秒低电平
CYCLE_TIME = 0.005  # 5毫秒总周期

# 全局变量，用于控制程序退出
running = True
chip = None
line = None

# 统计变量
pulse_count = 0
start_time = None

def signal_handler(signum, frame):
    """信号处理函数，用于优雅退出"""
    global running
    print("\n接收到退出信号，正在清理...")
    running = False

def cleanup():
    """清理GPIO资源"""
    global chip, line, pulse_count, start_time
    
    # 打印统计信息
    if start_time and pulse_count > 0:
        total_time = time.time() - start_time
        avg_interval = total_time / pulse_count
        print(f"\n统计信息:")
        print(f"总发送脉冲数: {pulse_count}")
        print(f"总运行时间: {total_time:.3f} 秒")
        print(f"平均脉冲间隔: {avg_interval:.6f} 秒 ({avg_interval*1000:.3f} 毫秒)")
        print(f"理论脉冲间隔: {CYCLE_TIME:.6f} 秒 ({CYCLE_TIME*1000:.3f} 毫秒)")
        if avg_interval > 0:
            deviation = abs(avg_interval - CYCLE_TIME) / CYCLE_TIME * 100
            print(f"时间偏差: {deviation:.2f}%")
    
    if line:
        line.release()
    if chip:
        chip.close()
    print("GPIO资源已释放")

def main():
    """主函数"""
    global running, chip, line, pulse_count, start_time
    
    # 设置信号处理器
    signal.signal(signal.SIGINT, signal_handler)   # Ctrl+C
    signal.signal(signal.SIGTERM, signal_handler)  # 终止信号
    
    try:
        # 获取GPIO芯片
        chip = gpiod.Chip('gpiochip0')
        
        # 获取GPIO20线路并设置为输出模式
        line = chip.get_line(GPIO_PIN)
        line.request(consumer="pwm_generator", type=gpiod.LINE_REQ_DIR_OUT)
        
        print(f"GPIO{GPIO_PIN} 已设置为输出模式")
        print("开始生成PWM信号...")
        print("按 Ctrl+C 退出程序")
        
        # 记录开始时间
        start_time = time.time()
        
        # 主循环：生成PWM信号
        while running:
            # 发送高电平信号
            line.set_value(1)
            time.sleep(HIGH_TIME)
            
            # 发送低电平信号
            line.set_value(0)
            time.sleep(LOW_TIME)
            
            # 增加脉冲计数
            pulse_count += 1
            
            # 如果高电平和低电平时间加起来小于总周期，则等待剩余时间
            remaining_time = CYCLE_TIME - (HIGH_TIME + LOW_TIME)
            if remaining_time > 0:
                time.sleep(remaining_time)
    
    except KeyboardInterrupt:
        print("\n程序被用户中断")
    except Exception as e:
        print(f"程序运行出错: {e}")
    finally:
        cleanup()

if __name__ == "__main__":
    main()
